﻿using BUGCOME.Infrastructure;
using BUGCOME.Model;
using BUGCOME.Model.Auth;
using BUGCOME.Model.Auth.dto;
using BUGCOME.ServiceCore.Filters;
using BUGCOME.ServiceCore.Services;
using BUGCOME.ServiceCore.Services.IServices;
using Microsoft.AspNetCore.Mvc;

namespace BUGCOME.Admin.Api.Controllers
{
    /// <summary>
    ///  字典数据API控制器
    /// </summary>
    [Route("adminapi/[controller]/[action]")]
    [ApiController]  // 标识为API控制器，自动处理模型验证等
    [ApiExplorerSettings(GroupName = "admin")]  // 文档分组为"common"
    public class MenuController : BaseController  // 继承基础控制器
    {
        private readonly IMenuService menuService;

        private readonly IRoleMenuService roleMenuService;

        private readonly IRoleService roleService;

        public MenuController(IMenuService menuService,
            IRoleMenuService roleMenuService,
            IRoleService roleService)
        {
            this.menuService = menuService;
            this.roleMenuService = roleMenuService;
            this.roleService = roleService;
        }

        /// <summary>
        /// 获取菜单树列表
        /// </summary>
        /// <returns></returns>
        [ActionPermissionFilter(Permission = "admin:menu:list")]
        [HttpPost]
        public async Task<IActionResult> TreeMenuList([FromBody] MenuQueryDto menu)
        {
            long userId = HttpContext.GetUId();
            return Success(await menuService.SelectTreeMenuListAsync(menu, userId), "yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>根据菜单编号获取详细信息</summary>
        /// <param name="dto">包含菜单ID的参数对象</param>
        /// <returns>菜单详细信息的成功响应</returns>
        [HttpPost]
        [ActionPermissionFilter(Permission = "admin:menu:query")]
        public async Task<IActionResult> GetMenuInfo([FromBody] ParmDto<long> dto)
        {
            return Success(await menuService.GetMenuByMenuIdAsync(dto.Value), "yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <param name="menuDto"></param>
        /// <returns></returns>
        [HttpPost]
        [Log(Title = "菜单修改", BusinessType = BusinessType.UPDATE)]
        [ActionPermissionFilter(Permission = "admin:menu:edit")]
        public async Task<IActionResult> MenuEdit([FromBody] MenuDto menuDto)
        {
            if (menuDto == null) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
            //if (UserConstants.NOT_UNIQUE.Equals(sysMenuService.CheckMenuNameUnique(MenuDto)))
            //{
            //    return ToResponse(ApiResult.Error($"修改菜单'{MenuDto.menuName}'失败，菜单名称已存在"));
            //}
            var config = new TypeAdapterConfig();
            //映射规则
            config.ForType<Menu, MenuDto>()
                .NameMatchingStrategy(NameMatchingStrategy.IgnoreCase);//忽略字段名称的大小写;//忽略除以上配置的所有字段

            var modal = menuDto.Adapt<Menu>(config).ToUpdate(HttpContext);
            if (UserConstants.YES_FRAME.Equals(modal.IsFrame) && (!modal.Path.StartsWith("http") && !modal.Path.StartsWith("/link")))
            {
                return ToResponse(ApiResult.Error($"修改菜单'{modal.MenuName}'失败，地址必须以http(s)://开头"));
            }
            if (modal.MenuId.Equals(modal.ParentId))
            {
                return ToResponse(ApiResult.Error($"修改菜单'{modal.MenuName}'失败，上级菜单不能选择自己"));
            }
            modal.UpdateBy = HttpContext.GetName();
            long result = await menuService.EditMenuAsync(modal);

            return ToResponse(result);
        }

        /// <summary>
        /// 菜单添加
        /// </summary>
        /// <param name="menuDto"></param>
        /// <returns></returns>
        [HttpPost]
        [Log(Title = "菜单添加", BusinessType = BusinessType.INSERT)]
        [ActionPermissionFilter(Permission = "admin:menu:add")]
        public async Task<IActionResult> MenuAdd([FromBody] MenuDto menuDto)
        {
            var config = new TypeAdapterConfig();
            //映射规则
            config.ForType<Menu, MenuDto>()
                .NameMatchingStrategy(NameMatchingStrategy.IgnoreCase);
            var menu = menuDto.Adapt<Menu>(config).ToCreate(HttpContext);

            if (menu == null) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
            if (UserConstants.NOT_UNIQUE.Equals(await menuService.CheckMenuNameUniqueAsync(menu)))
            {
                return ToResponse(ApiResult.Error($"新增菜单'{menu.MenuName}'失败，菜单名称已存在"));
            }
            if (UserConstants.YES_FRAME.Equals(menu.IsFrame) && !menu.Path.StartsWith("http"))
            {
                return ToResponse(ApiResult.Error($"新增菜单'{menu.MenuName}'失败，地址必须以http(s)://开头"));
            }
            var uid = HttpContext.GetUId();
            menu.CreateBy = HttpContext.GetName();
            long result =await menuService.AddMenuAsync(menu);
            if (result > 0)
            {
                var userRoles =await roleService.SelectUserRolesAsync(uid);
                var roleId = userRoles.FirstOrDefault();
                if (!await roleService.IsAdminAsync(uid) && roleId > 0)
                {
                   await roleService.InsertRoleMenuAsync(new RoleDto
                    {
                        CreateBy = menu.CreateBy,
                        RoleId = roleId,
                        MenuIds = [result]
                    });
                }
            }
            return ToResponse(result);
        }


        /// <summary>
        /// 根据菜单编号删除菜单
        /// </summary>
        /// <param name="dto">id</param>
        /// <returns></returns>
        [HttpPost]
        [Log(Title = "菜单根据菜单id删除", BusinessType = BusinessType.DELETE)]
        [ActionPermissionFilter(Permission = "admin:menu:remove")]
        public async Task<IActionResult> DeleteMenuById([FromBody]ParmDto<long> dto)
        {
            if (await menuService.HasChildByMenuIdAsync(dto.Value))
            {
                return ToResponse(ResultCode.CUSTOM_ERROR, "存在子菜单,不允许删除");
            }
            if (await roleMenuService.CheckMenuExistRoleAsync(dto.Value))
            {
                return ToResponse(ResultCode.CUSTOM_ERROR, "菜单已分配,不允许删除");
            }
            long result = await menuService.DeleteMenuByIdAsync(dto.Value);

            return ToResponse(result);
        }

        /// <summary>
        /// 根据菜单编号删除菜单及其所有子菜单
        /// </summary>
        /// <param name="dto">id</param>
        /// <returns></returns>
        [HttpPost]
        [Log(Title = "菜单根据菜单id删除并删除子集", BusinessType = BusinessType.DELETE)]
        [ActionPermissionFilter(Permission = "admin:menu:remove")]

        public async Task<IActionResult> DeleteAllMenuById([FromBody]ParmDto<long> dto)
        {
            long result =await menuService.DeleteAllMenuByIdAsync(dto.Value);

            return ToResponse(result);
        }
    }
}
